<template>
    <el-form
    class="topic bg-white p-5 cursor-pointe overflow-x-auto"
    :model="topic"
    :rules="rules"
    label-width="110"
    ref="formRef"
    >
        <div class="title flex items-center justify-between">
            <span>{{ indexText }}、{{ topicTypeText }}</span>
            <CardEditDelectIcon 
            class="function"
            :show-edit="false"
            @del="cancel"
            />
        </div>
        <el-form-item label="难度" prop="difficulty" class="mt-4">
            <el-input-number @change="onChange" v-model.number="topic.difficulty" :min="1" type="number" placeholder="请输入数字，越大难度越高" />
        </el-form-item>
        <el-form-item label="分值" prop="score" class="mt-4">
            <el-input-number @change="onChange" v-model.number="topic.score" :min="3" type="number" placeholder="请输入分值" />
        </el-form-item>
        <el-form-item label="内容" prop="content" class="mt-4">
            <el-input @focus="onFocus(props.item, 'content', $event)" :modelValue="getText(props.item.content)" placeholder="请输入" class="flex-1" />
        </el-form-item>
        <el-form-item label="同类型题目标注" prop="sameFlg" class="mt-4">
            <el-input v-model.string="topic.sameFlg"  placeholder="请输入" class="flex-1" />
        </el-form-item>
        <el-form-item label="所属分类" prop="categoryId" class="mt-4">
            <el-select 
            v-model="topic.categoryId" 
            @change="onChange" 
            filterable
            placeholder="选择或添加类型"
            allow-create
            >
                <el-option 
                v-for="item in props.categoryList" 
                :key="item.id"
                :value="item.id"
                :label="item.categoryName" 
                />
            </el-select>
        </el-form-item>
        <el-form-item 
        label="选项" 
        prop="options"
        v-if="topic.type == 2"
        class="option"
        >
            <!-- 多选 -->
            <el-checkbox-group 
            v-model="topic.currectOpt"
            @change="onChange"
            class="w-full"
            >
                <div
                v-for="(item, i) in topic.options"
                :key="item.item"
                class="flex items-center mb-3"
                >
                    <el-checkbox :label="item.item"><span></span></el-checkbox>
                    <el-input @focus="onFocus(item, 'itemContent', $event)" :modelValue="getText(item.itemContent)" placeholder="请输入" class="ml-2" />
                    <el-icon @click="topic.options.splice(i, 1);onChange();" class="flex-shrink-0 ml-2 f-12 color-gray"><CircleCloseFilled /></el-icon>
                </div>
            </el-checkbox-group>
            <div @click="addOption" v-show="topic.options.length < 10 && (topic.type == 2 || topic.type == 3)" class="add center w-full cursor-pointer">
                <svg class="iconpark-icon"><use href="#plus"></use></svg> 添加选项
            </div>
        </el-form-item>
        <el-form-item v-if="[1, 2, 3, 4, 5].includes(topic.type)" label="答案" prop="answer" class="mt-4">
            <div
            v-for="(answer, i) in topic.answers"
            :key="i"
            class="flex items-center mb-3 w-full"
            >
                <el-input @focus="onAnswerFocus(i, $event)" :modelValue="getText(answer)" placeholder="请输入答案" class="ml-2 w-full" />
                <el-button @click="onDelAnswer(i)" :icon="Delete" type="danger" size="small" class="ml-2" />
            </div>
            <div @click="addAnswer" class="add center w-full cursor-pointer">
                <svg class="iconpark-icon"><use href="#plus"></use></svg> 添加答案
            </div>
        </el-form-item>
        <el-form-item label="视频讲解" prop="vedio">
            <el-upload
            v-model:file-list="topic.video"
            :action="`${baseURL}/file/uploadVideo`"
            :on-remove="handleRemove"
            :on-success="handleVideoSuccess"
            :headers="uploadHeaders"
            accept="video/*"
            >
                <el-button type="primary">点击上传</el-button>
            </el-upload>
        </el-form-item>
        <el-form-item label="试题图片" prop="imgs">
            <el-upload
            v-model:file-list="topic.imgs"
            :action="`${baseURL}/file/upload`"
            list-type="picture-card"
            :on-remove="handleRemove"
            :on-success="handleImageSuccess"
            :headers="uploadHeaders"
            multiple
            accept="image/*"
            >
                <el-icon><Plus /></el-icon>
            </el-upload>
        </el-form-item>
    </el-form>
</template>

<script setup lang="ts">
import { toZhDigit, getText, baseURL, getCookie } from '@/Utils/utils';
import { computed, reactive, ref, watch } from 'vue';
import { CircleCloseFilled, Delete } from '@element-plus/icons-vue';
import { ElMessageBox, type FormInstance, type FormRules } from 'element-plus';
import CardEditDelectIcon from '@/Components/CardEditDelectIcon.vue';
import type { AnyObj, TopicSaveApi, TopicTypeNumber } from '@/Utils/type';
import { Plus } from '@element-plus/icons-vue';

const emit = defineEmits(['update:modelValue', 'change', 'del', 'addOpt', 'onFocus', 'addAnswer', 'setVedio', 'answerFocus']);

const formRef = ref<FormInstance>();

const props = defineProps<{
    index: number;
    item: TopicSaveApi;
    detail: any;
    categoryList: any[]
}>();

interface Topic {
    id: number;
    options: {
        item: string,
        itemContent: string;
    }[];
    currectOpt: string[];
    categoryId: number;
    categoryName: string;
    content: string;
    score: number;
    difficulty: number;
    imgs: {name: string; url: string}[];
    video: {name: string; url: string}[];
    type: TopicTypeNumber;
    answers: string[];
    sameFlg: string;
};

const uploadHeaders = reactive({
    userId: getCookie("userId"),
    token: getCookie("token"),
});

const rules = reactive<FormRules>({
    content: [
        { required: true, trigger: 'blur', message: '请输入题目' }
    ],
    options: [
        { 
            trigger: 'change',
            validator(rule, currectIds, callback) {
                if (props.item.type == 2) {
                    if (topic.options.length === 0) {
                        return callback(new Error("请添加选项"));
                    }
                    if (Array.isArray(topic.options) && topic.options.length <= 1) {
                        return callback(new Error("多选题至少选择两项"));
                    }
                    if (topic.options.some(item => !item.itemContent)) {
                        return callback(new Error("答案输入框不能为空"));
                    }
                }
                callback();
            }
        }
    ],
});

const indexText = computed(() => toZhDigit(props.index + 1));

const getTopic = () => {
    const item = props.item;
    const answers = (item.answers || []).map(answer => answer.content);
    // console.log('item', item);
    return <Topic>{
        id: item.id,
        options: item.choiceDtos,
        currectOpt: item.type == 2 ? answers : [],
        categoryId: item.categoryId,
        categoryName: item.categoryName,
        content: item.content,
        sameFlg: item.sameFlg,
        difficulty: item.difficulty,
        imgs: (item.imgs || []).map(url => {
            return {
                name: url,
                url
            }
        }),
        video: item.video ? [
            {
                name: item.video,
                url: item.video
            }
        ] : [],
        answers,
        type: props.item.type,
        score: props.item.score
    }
};

const topic = reactive<Topic>(getTopic());

const topicTypeText = computed(() => {
    return {
        1: '填空',
        2: '选择题',
        3: '计算题',
        4: '应用题',
        5: '判断题'
    }[props.item.type];
});

// 聚焦事件
const onFocus = (item: AnyObj, key: string | number, e?: any) => {
    e && e.target.blur();
    emit('onFocus', item, key);
};

// 答案选项聚焦事件
const onAnswerFocus = (i: number, e?: any) => {
    // e && e.target.blur();
    emit('answerFocus', i);
};

const onDelAnswer = (index: number) => {
    topic.answers.splice(index, 1);
    onChange();
};

const createParentTopic = () => {
    return <TopicSaveApi>{
        id: topic.id,
        categoryId: topic.categoryId,
        categoryName: topic.categoryName,
        choiceDtos: topic.options,
        answers: topic.answers.map(answer => {
            return {
                content: answer
            }
        }),
        content: topic.content,
        sameFlg: topic.sameFlg,
        score: topic.score,
        difficulty: topic.difficulty,
        imgs: topic.imgs.map(item => item.url),
        video: topic.video[0]?.url || '',
        type: topic.type,
    };
};

// 触发更新父组件事件
const onChange = () => {
    const topicItem = createParentTopic();
    emit('update:modelValue', topicItem);
    emit('change', topicItem);
};

const choiceDtosItem = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];

// 点击添加选项
const addOption = () => {
    // topic.topicOptionsList.push({
    //     isCorrect: 0,
    //     optionContent: '',
    //     optionId: 0,
    //     uid: createUuid(),
    // });
    topic.options.push({
        itemContent: '',
        item: choiceDtosItem[topic.options.length - 1] || ''
    });
    onChange();
};

// 点击添加答案
const addAnswer = () => {
    // topic.ansers.push('');
    // onChange();
    emit('addAnswer');
};

// 删除视频文
const handleRemove = () => {
    onChange();
};

// 上传视频成功
const handleVideoSuccess = (res: any) => {
    // console.log(fileList.value);
    if (res?.data?.url) {
        topic.video = [
            {
                name: res.data.url,
                url: res.data.url,
            }
        ];
    } else {
        if (topic.video.length > 0) {
            topic.video.length = 1;
        } else {
            topic.video = [];
        }
    }
    onChange();
};

// 上传图片成功
const handleImageSuccess = (res: any) => {
    if (res?.data?.url) {
        topic.imgs[topic.imgs.length - 1] = {
            name: res.data.url,
            url: res.data.url,
        };
    } else {
        topic.imgs.length = topic.imgs.length - 1;
    }
    onChange();
};

// 点击取消
const cancel = async () => {
    try {
        await ElMessageBox.confirm(
            '确认删除试题吗？',
            '提示',
            {
                confirmButtonText: '确定删除',
                cancelButtonText: '取消',
                type: 'warning',
            }
        );
        emit('del');
    } catch (error) {
        console.warn('error: ', error);
    }
};

watch(
    () => props.item,
    () => {
        // console.log('props.modelValue: ', props.modelValue);
        const newTopic = getTopic();
        topic.id = newTopic.id;
        topic.answers = newTopic.answers;
        topic.categoryId = newTopic.categoryId;
        topic.categoryName = newTopic.categoryName;
        topic.content = newTopic.content;
        topic.currectOpt = newTopic.currectOpt;
        topic.difficulty = newTopic.difficulty;
        topic.score = newTopic.score;
        topic.imgs = newTopic.imgs;
        topic.options = newTopic.options;
        topic.type = newTopic.type;
        topic.video = newTopic.video;
        // console.log('topic: ', topic);
    },
    {
        deep: true
    }
);

defineExpose({
    validate: () => formRef.value?.validate(),
    getData: () => topic,
    createParentTopic: createParentTopic
});
</script>

<style lang="scss" scoped>
.topic {
    border-radius: 4px;
    &:hover {
        .title {
            .function {
                visibility: visible;
            }
        }
    }
    .title {
        .function {
            visibility: hidden;
        }
    }
    .name {
        &::before {
            content: "*";
            margin-right: 4px;
            color: red;
            font-size: 12px;
        }
        &::after {
            content: '：';
        }
    }
    .option {
        .add {
            height: 32px;
            border-radius: 4px;
            border: 1px solid #E8E8E6;
            background: #FAFAF7;
        }
    }
    .answer {
        .name {
            &::before {
                content: "";
                margin-right: 9px;
            }
        }
    }
    .el-radio-item {
        margin-right: 10px;
    }
}
</style>